package com.easylinkin.linkappapi.webcammanage.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easylinkin.linkappapi.common.constant.CommonConstant;
import com.easylinkin.linkappapi.common.utils.file.FileExt;
import com.easylinkin.linkappapi.common.utils.file.ZipFileUtil;
import com.easylinkin.linkappapi.common.utils.io.OutputStreamUtil;
import com.easylinkin.linkappapi.elasticsearch.service.IEService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.mapper.LinkappTenantMapper;
import com.easylinkin.linkappapi.webcammanage.entity.ImageCapture;
import com.easylinkin.linkappapi.webcammanage.entity.ImageDeviceFlow;
import com.easylinkin.linkappapi.webcammanage.entity.QueryImageCapture;
import com.easylinkin.linkappapi.webcammanage.service.ImageCaptureService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * class info :
 *
 * @author liuqihang
 * @date 2021/6/18 10:39
 */
@Service
@Slf4j
public class ImageCaptureServiceImpl implements ImageCaptureService {

    @Resource
    IEService realService;

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    @Resource
    private LinkappTenantMapper linkappTenantMapper;

    @Override
    public IPage<ImageCapture> getPage(Page page, QueryImageCapture queryImageCapture) {
        SearchHits imageCaptureSearchInfo = getImageCaptureSearchInfo(page, queryImageCapture);
        if (imageCaptureSearchInfo == null) {
            return page;
        }
        log.info("es查询结果到设备历史数据条数 ：" + imageCaptureSearchInfo.getTotalHits());
        SearchHit[] hits = imageCaptureSearchInfo.getHits();
        page.setTotal(imageCaptureSearchInfo.totalHits);
        List<ImageCapture> imageCaptureList = getImageCaptureList(hits);
        page.setRecords(imageCaptureList);
        return page;
    }

    private SearchHits getImageCaptureSearchInfo(Page page, QueryImageCapture queryImageCapture){
        List<String> necessaryFieldList = new ArrayList<>();
        //抓拍图片地址字段
        necessaryFieldList.add("originImageKey");

        //租户隔离
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        LinkappTenant qw = new LinkappTenant();
        qw.setId(tenantId);
        LinkappTenant linkappTenant = linkappTenantMapper.selectLinkappTenant(qw);
        if(linkappTenant == null || linkappTenant.getProjectId() == null){
            return null;
        }

        Map<String, String> likeQueryMap = new HashMap<String, String>(16);
        likeQueryMap.put("deviceName", queryImageCapture.getDeviceName());
        likeQueryMap.put("projectId", linkappTenant.getProjectId());

        String indices = null;
        if(!StringUtils.isEmpty(queryImageCapture.getQueryTimeStart()) && !StringUtils.isEmpty(queryImageCapture.getQueryTimeEnd())){
            indices = realService.getIndicesListByDate(queryImageCapture.getQueryTimeStart(), queryImageCapture.getQueryTimeEnd());
        }

        SearchHits searchHits = realService.getDeviceDataListFromESByDeviceName(likeQueryMap,
                (int)page.getCurrent(), (int)page.getSize(),
                queryImageCapture.getQueryTimeStart(), queryImageCapture.getQueryTimeEnd(), necessaryFieldList, indices);
        return searchHits;
    }

    private List<ImageCapture> getImageCaptureList(SearchHit[] hits){
        List<ImageCapture> icList = new ArrayList<ImageCapture>();
        for (SearchHit searchHit : hits) {
            ImageDeviceFlow dr = JSON.parseObject(searchHit.getSourceAsString(), ImageDeviceFlow.class);

            //根据url获取文件相关属性
            FileExt fileInfoByUrl = ZipFileUtil.getFileInfoByUrl(dr.getData().getOriginImageKey());

            //重新封装数据返回前端
            ImageCapture ic = new ImageCapture().setDeviceName(dr.getDeviceName())
                    .setCaptureTime(dr.getData().getCaptureTime())
                    .setFileHttpUrl(dr.getData().getOriginImageKey())
                    .setFileSize(fileInfoByUrl.getFileSize())
                    .setFileName(fileInfoByUrl.getFileName());

            icList.add(ic);
        }
        return icList;
    }

    @Override
    public String batchDownloadZip(QueryImageCapture queryImageCapture, HttpServletRequest request, HttpServletResponse response) {
        String fileName = "图像抓拍批量导出";
        try {
            List<String> fileUrlList = null;
            if(queryImageCapture.getFileUrlList() == null || queryImageCapture.getFileUrlList().isEmpty()){
                //查询导出
                SearchHits imageCaptureSearchInfo = getImageCaptureSearchInfo(queryImageCapture.getPage(), queryImageCapture);
                if (imageCaptureSearchInfo == null || imageCaptureSearchInfo.getTotalHits() == 0) {
                    return "无记录";
                }

                List<ImageCapture> imageCaptureList = getImageCaptureList(imageCaptureSearchInfo.getHits());

                fileUrlList = imageCaptureList.stream().map(ImageCapture :: getFileHttpUrl).collect(Collectors.toList());
            }else {
                //选择导出
                fileUrlList = queryImageCapture.getFileUrlList();
            }

            List<FileExt> fileExtList = new ArrayList<>();
            for (String url:
                    fileUrlList) {
                FileExt fileInfoByUrl = ZipFileUtil.getFileInfoByUrl(url);
                fileExtList.add(fileInfoByUrl);
            }
            InputStream fileInputStream = ZipFileUtil.getFileInputStream(fileName, fileExtList);

            OutputStream outputStream = OutputStreamUtil
                    .getOutputStream(request, response, fileName + ZipFileUtil.zipSuffix);

            int ch;
            while ((ch = fileInputStream.read()) != -1) {
                outputStream.write(ch);
            }

            response.flushBuffer();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private String checkImageTotal(long listSize){
        if(listSize > CommonConstant.MAX_IMAGE_LIMIT){
            return "批量下载文件超过限制（20张），请分批次下载";
        }
        return null;
    }
}
